home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 60 / IOPROG_60.ISO / soft / c++ / gsl-1.1.1-setup.exe / {app} / src / histogram / find.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-14  |  1.9 KB  |  87 lines

  1. /* histogram/find.c
  2.  * 
  3.  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Brian Gough
  4.  * 
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or (at
  8.  * your option) any later version.
  9.  * 
  10.  * This program is distributed in the hope that it will be useful, but
  11.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * General Public License for more details.
  14.  * 
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. /* determines whether to optimize for linear ranges  */
  21. #define LINEAR_OPT 1
  22.  
  23. static int find (const size_t n, const double range[], 
  24.                  const double x, size_t * i);
  25.  
  26. static int
  27. find (const size_t n, const double range[], const double x, size_t * i)
  28. {
  29.   size_t i_linear, lower, upper, mid;
  30.  
  31.   if (x < range[0])
  32.     {
  33.       return -1;
  34.     }
  35.  
  36.   if (x >= range[n])
  37.     {
  38.       return +1;
  39.     }
  40.  
  41.   /* optimize for linear case */
  42.  
  43. #ifdef LINEAR_OPT
  44.   {
  45.     double u =  (x - range[0]) / (range[n] - range[0]);
  46.     i_linear = (size_t) (u * n);
  47.   }
  48.  
  49.   if (x >= range[i_linear] && x < range[i_linear + 1])
  50.     {
  51.       *i = i_linear;
  52.       return 0;
  53.     }
  54. #endif
  55.  
  56.   /* perform binary search */
  57.  
  58.   upper = n ;
  59.   lower = 0 ;
  60.  
  61.   while (upper - lower > 1)
  62.     {
  63.       mid = (upper + lower) / 2 ;
  64.       
  65.       if (x >= range[mid])
  66.         {
  67.           lower = mid ;
  68.         }
  69.       else
  70.         {
  71.           upper = mid ;
  72.         }
  73.     }
  74.  
  75.   *i = lower ;
  76.  
  77.   /* sanity check the result */
  78.  
  79.   if (x < range[lower] || x >= range[lower + 1])
  80.     {
  81.       GSL_ERROR ("x not found in range", GSL_ESANITY);
  82.     }
  83.  
  84.   return 0;
  85. }
  86.  
  87.